package com.qf.jwt.security.config;

import com.qf.common.constant.URLConstant;
import com.qf.common.core.domain.ResponseResult;
import com.qf.common.utils.ServletUtils;
import com.qf.jwt.filter.JwtAuthenticationTokenFilter;
import com.qf.jwt.security.auth.MyauthorizationManager;
import com.qf.jwt.security.exception.NoAuthenticationEntryPoint;
import com.qf.jwt.security.filter.UsernamePasswordJsonAuthenticationFilter;
import com.qf.jwt.security.handler.LoginFailHandler;
import com.qf.jwt.security.handler.LoginSuccessHandler;
import com.qf.jwt.util.SingletonRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;


/**
 * @author : sin
 * @date : 2024/6/11 13:00
 * @Description : 配置类
 */
@Slf4j
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {

    /**
     * 自定义权限校验
     */
    @Resource
    private MyauthorizationManager authorizationManager;

    @Resource
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        /**
         * 配置放行的访问接口
         * authorizationManager 授权
         */
        http.authorizeHttpRequests(auth -> auth
                        .mvcMatchers("/admin/**").access(authorizationManager)
                        .anyRequest().permitAll()
                ).exceptionHandling()
                .accessDeniedHandler(new CustomAccessDeniedHandler())
                .and()
                .httpBasic(); // 使用 HTTP Basic 认证

        /**
         * 配置自定义登录
         */
        http.logout(e -> e.logoutUrl(URLConstant.LOGOUT_URL).logoutSuccessHandler((request, response, authentication) -> {
                    ServletUtils.renderString(response, ResponseResult.success("退出成功"));
                })
        );

        // 配置身份验证异常处理
        http.exceptionHandling(e -> e.authenticationEntryPoint(new NoAuthenticationEntryPoint()));

        // 验证码拦截器
//        http.addFilterBefore(new VerifyCodeFilter(), UsernamePasswordAuthenticationFilter.class);

        // jwt拦截器
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        // 跨域漏洞防御 关闭
        http.csrf(e -> e.disable());

        // 跨域拦截 关闭
        http.cors(e -> e.disable());

        return http.build();
    }

    @Autowired
    AuthenticationConfiguration authenticationConfiguration;
    /**
     * 自定义登录拦截器
     */
    @Bean
    UsernamePasswordJsonAuthenticationFilter usernamePasswordJsonAuthenticationFilter() throws Exception {

        UsernamePasswordJsonAuthenticationFilter authenticationFilter = new UsernamePasswordJsonAuthenticationFilter();
        authenticationFilter.setAuthenticationSuccessHandler(new LoginSuccessHandler());
        authenticationFilter.setAuthenticationFailureHandler(new LoginFailHandler());
        authenticationFilter.setAuthenticationManager(authenticationConfiguration.getAuthenticationManager());
        return authenticationFilter;
    }

    /**
     * 强散列哈希加密实现
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return SingletonRegistry.getInstance().getPasswordEncoder();
    }

}
